package tool;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;

import java.util.Stack;
import java.util.regex.Pattern;

public class FastJsonRepairer {

    /**
     * 修复JSON字符串，支持各种格式问题和多层转义处理
     */
    public static String repairJson(String jsonString) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return "{}";
        }
        jsonString = repairMultiLayerJson(jsonString);
        // 检查字符串是否已经被转义处理过
        if (isAlreadyEscaped(jsonString)) {
            return processAlreadyEscapedJson(jsonString);
        }

        // 预处理：移除注释和修复明显的格式问题
        String preprocessed = preprocessJson(jsonString);

        try {
            // 尝试直接解析
            Object parsed = JSON.parse(preprocessed,
                    Feature.AllowSingleQuotes,
                    Feature.AllowUnQuotedFieldNames,
                    Feature.AllowArbitraryCommas
            );

            // 递归处理嵌套的JSON字符串
            Object processed = recursivelyProcessNestedJson(parsed);

            return JSON.toJSONString(processed);
        } catch (JSONException e) {
            // 如果直接解析失败，尝试更复杂的修复
            return complexRepair(preprocessed);
        }
    }

    /**
     * 检查字符串是否已经被转义处理过
     */
    private static boolean isAlreadyEscaped(String jsonString) {
        // 检查是否包含 \" 而不是 \\"
        return jsonString.contains("\\\"") && !jsonString.contains("\\\\\\\"");
    }

    /**
     * 处理已经被转义过的JSON字符串
     */
    private static String processAlreadyEscapedJson(String jsonString) {
        try {
            // 直接解析最外层JSON
            JSONObject outerJson = JSON.parseObject(jsonString,
                    Feature.AllowSingleQuotes,
                    Feature.AllowUnQuotedFieldNames,
                    Feature.AllowArbitraryCommas
            );

            // 处理嵌套的JSON字段
            processNestedFields(outerJson);

            return JSON.toJSONString(outerJson);
        } catch (Exception e) {
            // 如果解析失败，尝试修复后重试
            String fixed = fixCommonFormatIssues(jsonString);
            return processAlreadyEscapedJson(fixed);
        }
    }

    /**
     * 处理嵌套的JSON字段
     */
    private static void processNestedFields(JSONObject json) {
        for (String key : json.keySet()) {
            Object value = json.get(key);

            if (value instanceof String) {
                String strValue = (String) value;

                // 检查是否是嵌套的JSON字符串
                if (isJsonString(strValue)) {
                    try {
                        // 尝试解析嵌套的JSON
                        Object nested = JSON.parse(strValue,
                                Feature.AllowSingleQuotes,
                                Feature.AllowUnQuotedFieldNames,
                                Feature.AllowArbitraryCommas
                        );

                        // 如果是JSON对象，递归处理
                        if (nested instanceof JSONObject) {
                            processNestedFields((JSONObject) nested);
                        }

                        json.put(key, nested);
                    } catch (Exception e) {
                        // 如果解析失败，尝试修复后重试
                        String fixed = unescapeJsonString(strValue);
                        if (!fixed.equals(strValue)) {
                            try {
                                Object nested = JSON.parse(fixed,
                                        Feature.AllowSingleQuotes,
                                        Feature.AllowUnQuotedFieldNames,
                                        Feature.AllowArbitraryCommas
                                );
                                json.put(key, nested);
                            } catch (Exception e2) {
                                // 如果仍然失败，保留原始值
                            }
                        }
                    }
                }
            } else if (value instanceof JSONObject) {
                // 递归处理嵌套对象
                processNestedFields((JSONObject) value);
            }
        }
    }

    /**
     * 检查字符串是否是JSON格式
     */
    private static boolean isJsonString(String str) {
        if (str == null || str.length() < 2) {
            return false;
        }

        String trimmed = str.trim();
        return (trimmed.startsWith("{") && trimmed.endsWith("}")) ||
                (trimmed.startsWith("[") && trimmed.endsWith("]"));
    }

    /**
     * 递归处理嵌套的JSON字符串
     */
    private static Object recursivelyProcessNestedJson(Object obj) {
        if (obj instanceof JSONObject) {
            JSONObject jsonObj = (JSONObject) obj;
            for (String key : jsonObj.keySet()) {
                Object value = jsonObj.get(key);
                if (value instanceof String) {
                    // 尝试解析字符串中的JSON
                    Object parsedValue = tryParseNestedJson((String) value);
                    jsonObj.put(key, recursivelyProcessNestedJson(parsedValue));
                } else {
                    jsonObj.put(key, recursivelyProcessNestedJson(value));
                }
            }
            return jsonObj;
        } else if (obj instanceof String) {
            // 如果是字符串，尝试解析其中的JSON
            return tryParseNestedJson((String) obj);
        }
        return obj;
    }

    /**
     * 尝试解析嵌套的JSON字符串
     */
    private static Object tryParseNestedJson(String str) {
        // 如果字符串看起来不像JSON，直接返回
        if (str == null || str.length() < 2 ||
                (!str.trim().startsWith("{") && !str.trim().startsWith("["))) {
            return str;
        }

        // 尝试直接解析
        try {
            Object parsed = JSON.parse(str,
                    Feature.AllowSingleQuotes,
                    Feature.AllowUnQuotedFieldNames,
                    Feature.AllowArbitraryCommas
            );
            return recursivelyProcessNestedJson(parsed);
        } catch (Exception e) {
            // 如果直接解析失败，尝试去除一层转义
            String unescaped = unescapeJsonString(str);
            if (!unescaped.equals(str)) {
                return tryParseNestedJson(unescaped);
            }

            // 如果去除转义后还是无法解析，返回原始字符串
            return str;
        }
    }

    /**
     * 去除JSON字符串中的一层转义
     */
    private static String unescapeJsonString(String jsonStr) {
        if (jsonStr == null || jsonStr.isEmpty()) {
            return jsonStr;
        }

        // 检查字符串是否被多余的引号包裹
        String trimmed = jsonStr.trim();
        if (trimmed.startsWith("\"") && trimmed.endsWith("\"")) {
            trimmed = trimmed.substring(1, trimmed.length() - 1);
        }

        // 替换转义的双引号
        String unescaped = trimmed.replace("\\\"", "\"");
        // 替换转义的反斜杠
        unescaped = unescaped.replace("\\\\", "\\");

        return unescaped;
    }

    /**
     * 预处理JSON字符串，移除注释和进行基本清理
     */
    private static String preprocessJson(String json) {
        // 移除单行注释
        String noComments = removeSingleLineComments(json);

        // 移除多行注释
        noComments = removeMultiLineComments(noComments);

        // 修复常见的格式问题
        noComments = fixCommonFormatIssues(noComments);

        return noComments.trim();
    }

    /**
     * 移除单行注释
     */
    private static String removeSingleLineComments(String json) {
        StringBuilder result = new StringBuilder();
        boolean inString = false;
        boolean escapeNext = false;

        for (int i = 0; i < json.length(); i++) {
            char c = json.charAt(i);

            if (escapeNext) {
                result.append(c);
                escapeNext = false;
                continue;
            }

            if (c == '\\') {
                result.append(c);
                escapeNext = true;
                continue;
            }

            if (c == '"') {
                inString = !inString;
                result.append(c);
            } else if (!inString && c == '/' && i + 1 < json.length() && json.charAt(i + 1) == '/') {
                // 找到单行注释开始，跳过直到行尾
                while (i < json.length() && json.charAt(i) != '\n') {
                    i++;
                }
                if (i < json.length()) {
                    result.append('\n');
                }
            } else {
                result.append(c);
            }
        }

        return result.toString();
    }

    /**
     * 移除多行注释
     */
    private static String removeMultiLineComments(String json) {
        StringBuilder result = new StringBuilder();
        boolean inString = false;
        boolean escapeNext = false;

        for (int i = 0; i < json.length(); i++) {
            char c = json.charAt(i);

            if (escapeNext) {
                result.append(c);
                escapeNext = false;
                continue;
            }

            if (c == '\\') {
                result.append(c);
                escapeNext = true;
                continue;
            }

            if (c == '"') {
                inString = !inString;
                result.append(c);
            } else if (!inString && c == '/' && i + 1 < json.length() && json.charAt(i + 1) == '*') {
                // 找到多行注释开始，跳过直到注释结束
                i += 2; // 跳过/*
                while (i + 1 < json.length() && !(json.charAt(i) == '*' && json.charAt(i + 1) == '/')) {
                    i++;
                }
                i++; // 跳过*/
            } else {
                result.append(c);
            }
        }

        return result.toString();
    }

    /**
     * 修复常见的JSON格式问题
     */
    private static String fixCommonFormatIssues(String json) {
        // 修复JavaScript风格的布尔值和null值
        String fixed = json
                .replaceAll(":\\s*true\\b", ": true")
                .replaceAll(":\\s*false\\b", ": false")
                .replaceAll(":\\s*null\\b", ": null");

        // 修复单引号字符串
        fixed = fixSingleQuotes(fixed);

        // 修复未加引号的键名
        fixed = fixUnquotedKeys(fixed);

        // 移除尾随逗号
        fixed = removeTrailingCommas(fixed);

        return fixed;
    }

    /**
     * 修复单引号字符串
     */
    private static String fixSingleQuotes(String json) {
        StringBuilder result = new StringBuilder();
        boolean inDoubleQuotes = false;
        boolean inSingleQuotes = false;
        boolean escapeNext = false;

        for (int i = 0; i < json.length(); i++) {
            char c = json.charAt(i);

            if (escapeNext) {
                result.append(c);
                escapeNext = false;
                continue;
            }

            if (c == '\\') {
                result.append(c);
                escapeNext = true;
                continue;
            }

            if (c == '"' && !inSingleQuotes) {
                inDoubleQuotes = !inDoubleQuotes;
                result.append(c);
            } else if (c == '\'' && !inDoubleQuotes) {
                inSingleQuotes = !inSingleQuotes;
                result.append('"');
            } else {
                result.append(c);
            }
        }

        return result.toString();
    }

    /**
     * 修复未加引号的键名
     */
    private static String fixUnquotedKeys(String json) {
        // 使用正则表达式匹配未加引号的键名
        Pattern pattern = Pattern.compile("(\\{|\\,)\\s*([a-zA-Z_][a-zA-Z0-9_]*)\\s*:");
        java.util.regex.Matcher matcher = pattern.matcher(json);
        StringBuffer result = new StringBuffer();

        while (matcher.find()) {
            matcher.appendReplacement(result, matcher.group(1) + " \"" + matcher.group(2) + "\":");
        }
        matcher.appendTail(result);

        return result.toString();
    }

    /**
     * 移除尾随逗号
     */
    private static String removeTrailingCommas(String json) {
        StringBuilder result = new StringBuilder();
        boolean inString = false;
        boolean escapeNext = false;
        Stack<Character> braceStack = new Stack<>();

        for (int i = 0; i < json.length(); i++) {
            char c = json.charAt(i);

            if (escapeNext) {
                result.append(c);
                escapeNext = false;
                continue;
            }

            if (c == '\\') {
                result.append(c);
                escapeNext = true;
                continue;
            }

            if (c == '"') {
                inString = !inString;
                result.append(c);
            } else if (!inString) {
                if (c == '{' || c == '[') {
                    braceStack.push(c);
                    result.append(c);
                } else if (c == '}' || c == ']') {
                    if (!braceStack.isEmpty()) {
                        braceStack.pop();
                    }
                    // 检查并移除前面的逗号
                    int j = result.length() - 1;
                    while (j >= 0 && Character.isWhitespace(result.charAt(j))) {
                        j--;
                    }
                    if (j >= 0 && result.charAt(j) == ',') {
                        result.deleteCharAt(j);
                    }
                    result.append(c);
                } else {
                    result.append(c);
                }
            } else {
                result.append(c);
            }
        }

        return result.toString();
    }

    /**
     * 复杂修复 - 当Fastjson直接解析失败时使用
     */
    private static String complexRepair(String json) {
        try {
            // 尝试分段解析
            return tryPartialParse(json);
        } catch (Exception e) {
            // 如果分段解析也失败，返回空对象
            return "{}";
        }
    }

    /**
     * 尝试分段解析JSON
     */
    private static String tryPartialParse(String json) {
        // 尝试解析为JSON对象
        if (json.trim().startsWith("{")) {
            try {
                JSONObject obj = JSON.parseObject(json,
                        Feature.AllowSingleQuotes,
                        Feature.AllowUnQuotedFieldNames,
                        Feature.AllowArbitraryCommas
                );
                return JSON.toJSONString(obj);
            } catch (JSONException e) {
                // 提取可能有效的部分
                String extracted = extractPossibleJson(json);
                if (!extracted.equals(json)) {
                    return tryPartialParse(extracted);
                }
                throw e;
            }
        }

        // 尝试解析为JSON数组
        if (json.trim().startsWith("[")) {
            try {
                Object array = JSON.parse(json,
                        Feature.AllowSingleQuotes,
                        Feature.AllowUnQuotedFieldNames,
                        Feature.AllowArbitraryCommas
                );
                return JSON.toJSONString(array);
            } catch (JSONException e) {
                // 提取可能有效的部分
                String extracted = extractPossibleJson(json);
                if (!extracted.equals(json)) {
                    return tryPartialParse(extracted);
                }
                throw e;
            }
        }

        // 如果既不是对象也不是数组，尝试包装为对象
        return tryParseAsValue(json);
    }

    /**
     * 尝试将内容解析为JSON值
     */
    private static String tryParseAsValue(String json) {
        try {
            // 尝试直接解析为值
            Object value = JSON.parse("{\"value\":" + json + "}",
                    Feature.AllowSingleQuotes,
                    Feature.AllowUnQuotedFieldNames,
                    Feature.AllowArbitraryCommas
            );
            JSONObject wrapper = (JSONObject) value;
            // 提取value字段的值
            if (wrapper.containsKey("value")) {
                return JSON.toJSONString(wrapper.get("value"));
            }
            return "null";
        } catch (Exception e) {
            // 如果失败，尝试用引号包装
            try {
                return "\"" + json.replace("\"", "\\\"") + "\"";
            } catch (Exception e2) {
                return "null";
            }
        }
    }

    /**
     * 从损坏的JSON中提取可能有效的部分
     */
    private static String extractPossibleJson(String json) {
        // 查找第一个完整的大括号对
        int firstBrace = json.indexOf('{');
        if (firstBrace >= 0) {
            int matchingBrace = findMatchingBrace(json, firstBrace, '{', '}');
            if (matchingBrace > firstBrace) {
                return json.substring(firstBrace, matchingBrace + 1);
            }
        }

        // 查找第一个完整的中括号对
        int firstBracket = json.indexOf('[');
        if (firstBracket >= 0) {
            int matchingBracket = findMatchingBrace(json, firstBracket, '[', ']');
            if (matchingBracket > firstBracket) {
                return json.substring(firstBracket, matchingBracket + 1);
            }
        }

        // 如果没有完整结构，返回原始字符串
        return json;
    }

    /**
     * 找到匹配的括号
     */
    private static int findMatchingBrace(String str, int start, char open, char close) {
        int count = 1;
        for (int i = start + 1; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c == open) {
                count++;
            } else if (c == close) {
                count--;
                if (count == 0) {
                    return i;
                }
            }
        }
        return -1; // 没有找到匹配的括号
    }

    /**
     * 修复多层转义的JSON字符串
     */
    public static String repairMultiLayerJson(String jsonString) {
        if (jsonString == null || jsonString.trim().isEmpty()) {
            return "{}";
        }

        try {
            // 1. 首先尝试直接解析
            JSONObject parsed = JSON.parseObject(jsonString,
                    Feature.AllowSingleQuotes,
                    Feature.AllowUnQuotedFieldNames,
                    Feature.AllowArbitraryCommas
            );

            // 2. 递归处理所有嵌套的JSON字符串字段
            processNestedJsonFields(parsed);

            return JSON.toJSONString(parsed, true);
        } catch (Exception e) {
            // 3. 如果直接解析失败，尝试逐步去除转义层
            return tryStepByStepUnescaping(jsonString);
        }
    }

    /**
     * 递归处理嵌套的JSON字段
     */
    private static void processNestedJsonFields(JSONObject json) {
        for (String key : json.keySet()) {
            Object value = json.get(key);

            if (value instanceof String) {
                String strValue = (String) value;

                // 检查是否是嵌套的JSON字符串
                if (isLikelyJsonString(strValue)) {
                    try {
                        // 尝试解析嵌套的JSON
                        Object nested = tryParseNestedJson(strValue);
                        json.put(key, nested);

                        // 如果是JSON对象，递归处理
                        if (nested instanceof JSONObject) {
                            processNestedJsonFields((JSONObject) nested);
                        }
                    } catch (Exception e) {
                        // 如果解析失败，保留原始值
                    }
                }
            } else if (value instanceof JSONObject) {
                // 递归处理嵌套对象
                processNestedJsonFields((JSONObject) value);
            }
        }
    }

    /**
     * 检查字符串是否可能是JSON
     */
    private static boolean isLikelyJsonString(String str) {
        if (str == null || str.length() < 2) {
            return false;
        }

        String trimmed = str.trim();
        return (trimmed.startsWith("{") && trimmed.endsWith("}")) ||
                (trimmed.startsWith("[") && trimmed.endsWith("]")) ||
                (trimmed.startsWith("\"") && trimmed.endsWith("\"") &&
                        trimmed.length() > 2 && trimmed.contains(":"));
    }

    /**
     * 尝试逐步去除转义层
     */
    private static String tryStepByStepUnescaping(String jsonString) {
        // 尝试多次去除转义，直到可以解析为止
        for (int i = 0; i < 5; i++) {
            try {
                String unescaped = unescapeJsonString(jsonString);
                if (unescaped.equals(jsonString)) {
                    break; // 没有再变化，停止尝试
                }

                JSONObject parsed = JSON.parseObject(unescaped,
                        Feature.AllowSingleQuotes,
                        Feature.AllowUnQuotedFieldNames,
                        Feature.AllowArbitraryCommas
                );

                // 处理嵌套字段
                processNestedJsonFields(parsed);
                return JSON.toJSONString(parsed, true);
            } catch (Exception e) {
                // 继续尝试下一层
                jsonString = unescapeJsonString(jsonString);
            }
        }

        // 如果所有尝试都失败，返回空对象
        return "{}";
    }

    // 测试方法
    public static void main(String[] args) {
        // 测试多层转义的JSON字符串
        String s = "{\"method\":\"ResourceBackListener.process\",\"requestData\":\"\\\"{\\\\\\\"commandCategoryId\\\\\\\":4833146901715356113,\\\\\\\"instanceId\\\\\\\":4823634116090372483,\\\\\\\"isError\\\\\\\":\\\\\\\"true\\\\\\\",\\\\\\\"requestId\\\\\\\":\\\\\\\"d1d7256c-cc83-4f88-a3d7-1b0b242800ce\\\\\\\",\\\\\\\"serverType\\\\\\\":\\\\\\\"1834\\\\\\\",\\\\\\\"requestParams\\\\\\\":\\\\\\\"{\\\\\\\\\\\\\\\"tenant_id\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"4813278056586346510\\\\\\\",\\\\\\\\\\\\\\\"cloud_code\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"wocloud\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"region_id\\\\\\\\\\\\\\\":4813278056586346496,\\\\\\\\\\\\\\\"action\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"instanceBackup.wal.create\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"type\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"pgrds\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"request_id\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"d1d7256c-cc83-4f88-a3d7-1b0b242800ce\\\\\\\\\\\\\\\",\\\\\\\\\\\\\\\"url_param\\\\\\\\\\\\\\\":{\\\\\\\\\\\\\\\"instanceId\\\\\\\\\\\\\\\":4822198789559607704,\\\\\\\\\\\\\\\"rds_id\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"ebb12984-76b1-417e-a918-4288acc3443b\\\\\\\\\\\\\\\"}}\\\\\\\",\\\\\\\"responseParams\\\\\\\":\\\\\\\"{\\\\\\\\\\\\\\\"code\\\\\\\\\\\\\\\":422,\\\\\\\\\\\\\\\"data\\\\\\\\\\\\\\\":{\\\\\\\\\\\\\\\"unprocessedEntity\\\\\\\\\\\\\\\":{\\\\\\\\\\\\\\\"code\\\\\\\\\\\\\\\":422,\\\\\\\\\\\\\\\"message\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"No WAL file(s) to backup from instance ebb12984-76b1-417e-a918-4288acc3443b.\\\\\\\\\\\\\\\"}},\\\\\\\\\\\\\\\"requestId\\\\\\\\\\\\\\\":\\\\\\\\\\\\\\\"d1d7256c-cc83-4f88-a3d7-1b0b242800ce\\\\\\\\\\\\\\\"}\\\\\\\",\\\\\\\"methodCode\\\\\\\":\\\\\\\"instanceBackup.wal.create\\\\\\\"}\\\"\",\"requestMethod\":\"QUEUE\",\"responseData\":\"null\",\"serviceCode\":\"server\",\"url\":\"resource_back_queue\"}";

        String ss = "{\\\"commandCategoryId\\\":4833146901715356113,\\\"instanceId\\\":4823634116090372483,\\\"isError\\\":\\\"true\\\",\\\"requestId\\\":\\\"d1d7256c-cc83-4f88-a3d7-1b0b242800ce\\\",\\\"serverType\\\":\\\"1834\\\",\\\"requestParams\\\":\\\"{\\\\\\\"tenant_id\\\\\\\":\\\\\\\"4813278056586346510\\\\\\\",\\\\\\\"cloud_code\\\\\\\":\\\\\\\"wocloud\\\\\\\",\\\\\\\"region_id\\\\\\\":4813278056586346496,\\\\\\\"action\\\\\\\":\\\\\\\"instanceBackup.wal.create\\\\\\\",\\\\\\\"type\\\\\\\":\\\\\\\"pgrds\\\\\\\",\\\\\\\"request_id\\\\\\\":\\\\\\\"d1d7256c-cc83-4f88-a3d7-1b0b242800ce\\\\\\\",\\\\\\\"url_param\\\\\\\":{\\\\\\\"instanceId\\\\\\\":4822198789559607704,\\\\\\\"rds_id\\\\\\\":\\\\\\\"ebb12984-76b1-417e-a918-4288acc3443b\\\\\\\"}}\\\",\\\"responseParams\\\":\\\"{\\\\\\\"code\\\\\\\":422,\\\\\\\"data\\\\\\\":{\\\\\\\"unprocessedEntity\\\\\\\":{\\\\\\\"code\\\\\\\":422,\\\\\\\"message\\\\\\\":\\\\\\\"No WAL file(s) to backup from instance ebb12984-76b1-417e-a918-4288acc3443b.\\\\\\\"}},\\\\\\\"requestId\\\\\\\":\\\\\\\"d1d7256c-cc83-4f88-a3d7-1b0b242800ce\\\\\\\"}\\\",\\\"methodCode\\\":\\\"instanceBackup.wal.create\\\"}";

        String repairedBadJson = repairJson(ss);
        System.out.println("\n修复后的JSON:");
        System.out.println(repairedBadJson);
    }
}